package test1;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.BeforeAdvice;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.framework.AopContext;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor;
import org.springframework.aop.support.DefaultPointcutAdvisor;

import java.lang.reflect.Method;

/**
 * @author: mornd
 * @dateTime: 2023/5/17 - 4:22
 */
public class Demo {
    /**
     * aspect=通知（advice） + 切点（pointCut），一个切面类种可能有一到多个通知方法
     * advisor=更细粒度的切面，包含一个通知个切点
     */
    public static void main(String[] args) {
        ProxyFactory factory = new ProxyFactory();
        factory.setTarget(new Target1()); // 设置目标对象
        // 添加切点
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("execution(* foo(..))");

        // 添加环绕通知 MethodInterceptor
//        factory.addAdvice(new MethodInterceptor() {
//            @Override
//            public Object invoke(MethodInvocation invocation) throws Throwable {
//                System.out.println("before...");
//                return invocation.proceed();
//            }
//        });

        factory.addAdvisor(new DefaultPointcutAdvisor(pointcut, (MethodInterceptor) invocation -> {
            System.out.println("before...");
            return invocation.proceed();
        }));
//        factory.addInterface(I1.class); // 切换为 jdk 动态代理
//        factory.setProxyTargetClass(true); // true强制使用cglib

        // 获取代理对象
        Target1 proxy = (Target1) factory.getProxy();
        System.out.println(proxy.getClass());
        proxy.foo();
        proxy.bar();

    }

    static interface I1 {
        void foo();
        void bar();
    }

    static class Target1 implements I1 {

        @Override
        public void foo() {
            System.out.println("foo...");
        }

        @Override
        public void bar() {
            System.out.println("bar...");
        }
    }
}
